package com.zheng.redpacket.server.serivce.Impl;

import com.google.common.base.Strings;
import com.zheng.redpacket.mdg.mapper.PraiseMapper;
import com.zheng.redpacket.mdg.model.PraiseRankDto;
import com.zheng.redpacket.server.serivce.RedisPraiseService;
import org.redisson.api.RList;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisPraiseServiceImpl implements RedisPraiseService {
    private static final Logger LOGGER = LoggerFactory.getLogger(RedisPraiseService.class);
    private static final String KEY_PREFIX = "BlogPraiseMap";

    @Autowired
    RedissonClient redisson;
    @Autowired
    PraiseMapper praiseMapper;

    @Override
    public void cachePraiseBlog(Integer blogId, Integer userId, Integer status) throws Exception {
        final String key = new StringBuffer("redissonLock").append(blogId).append(userId).append(status).toString();
        RLock lock = redisson.getLock(key);
        //获取分布式锁（可重入）
        boolean locked = lock.tryLock(100, 10, TimeUnit.SECONDS);
        try {
            if (locked) {
                if (blogId != null && userId != null && status != null) {
                    final String redisKey = blogId + ":" + userId;
                    RMap<String, Integer> praiseMap = redisson.getMap(KEY_PREFIX);
                    /**
                     * status==1点赞操作
                     * status==0取消赞
                     */
                    if (status == 1) {
                        praiseMap.putIfAbsent(redisKey, userId);
                    } else if (status == 0) {
                        praiseMap.remove(redisKey);
                    }
                }
            }
        } catch (Exception e) {
            throw e;
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }
    }

    @Override
    public Long getCacheTotalBlog(Integer blogId) throws Exception {
        Long result = 0L;
        if (blogId != null) {
            RMap<String, Integer> praiseMap = redisson.getMap(KEY_PREFIX);
            Map<String, Integer> data = praiseMap.readAllMap();
            if (data != null && data.keySet() != null) {
                Set<String> keySet = data.keySet();
                Integer bId;
                for (String key : keySet) {
                    if (!Strings.isNullOrEmpty(key)) {
                        String[] arr = key.split(":");
                        if (arr != null && arr.length > 0) {
                            bId = Integer.valueOf(arr[0]);
                            if (blogId.equals(bId)) {
                                result += 1;
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

    @Override
    public void rankBlogPraise() throws Exception {
        final String key = "praiseRankList";
        List<PraiseRankDto> rank = praiseMapper.getPraiseRank();
        if (!CollectionUtils.isEmpty(rank) && rank.size() > 0){
            RList<PraiseRankDto> rankList = redisson.getList(key);
            //先清空之前的缓存
            rankList.clear();
            //将最新数据插入redis
            rankList.addAll(rank);
        }
    }

    @Override
    public List<PraiseRankDto> getBlogPraiseRank() throws Exception {
        final String key = "praiseRankList";
        RList<PraiseRankDto> rankList = redisson.getList(key);
        return rankList.readAll();
    }
}
